package com.gwtsz.chart.renderer;

import android.graphics.Canvas;
import android.graphics.Paint;
import com.gwtsz.chart.animation.ChartAnimator;
import com.gwtsz.chart.data.CandleData;
import com.gwtsz.chart.data.CandleEntry;
import com.gwtsz.chart.data.StickData;
import com.gwtsz.chart.highlight.Highlight;
import com.gwtsz.chart.interfaces.dataprovider.CandleDataProvider;
import com.gwtsz.chart.interfaces.dataprovider.StickDataProvider;
import com.gwtsz.chart.interfaces.datasets.ICandleDataSet;
import com.gwtsz.chart.utils.ColorTemplate;
import com.gwtsz.chart.utils.Transformer;
import com.gwtsz.chart.utils.Utils;
import com.gwtsz.chart.utils.ViewPortHandler;
import java.util.List;

/**
 * Created by spence on 17-3-23.
 */

public class StickShapeChartRenderer extends LineScatterCandleRadarRenderer {

  protected StickDataProvider mChart;

  private float[] mShadowBuffers = new float[8];
  private float[] mBodyBuffers = new float[4];
  private float[] mRangeBuffers = new float[4];
  private float[] mOpenBuffers = new float[4];
  private float[] mCloseBuffers = new float[4];
  public StickShapeChartRenderer(StickDataProvider chart, ChartAnimator animator,
      ViewPortHandler viewPortHandler) {
    super(animator, viewPortHandler);
    mChart=chart;
  }

  @Override public void drawData(Canvas c) {
    StickData stickData = mChart.getStickData();

    for (ICandleDataSet set : stickData.getDataSets()) {

      if (set.isVisible() && set.getEntryCount() > 0)
        drawDataSet(c, set);
    }
  }

   protected void drawDataSet(Canvas c, ICandleDataSet dataSet) {
    Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());

    float phaseX = Math.max(0.f, Math.min(1.f, mAnimator.getPhaseX()));
    float phaseY = mAnimator.getPhaseY();
    float barSpace = dataSet.getBarSpace();
    boolean showCandleBar = dataSet.getShowCandleBar();

    int minx = Math.max(mMinX, 0);
    int maxx = Math.min(mMaxX + 1, dataSet.getEntryCount());

    mRenderPaint.setStrokeWidth(dataSet.getShadowWidth());

    // draw the body
    for (int j = minx,
        count = (int) Math.ceil((maxx - minx) * phaseX + (float)minx);
        j < count;
        j++) {

      // get the entry
      CandleEntry e = dataSet.getEntryForIndex(j);

      final int xIndex = e.getXIndex();

      if (xIndex < minx || xIndex >= maxx)
        continue;

      final float open = e.getOpen();
      final float close = e.getClose();
      final float high = e.getHigh();
      final float low = e.getLow();

      if (showCandleBar) {
        // calculate the shadow

        mShadowBuffers[0] = xIndex;
        mShadowBuffers[2] = xIndex;
        mShadowBuffers[4] = xIndex;
        mShadowBuffers[6] = xIndex;

        if (open > close) {
          mShadowBuffers[1] = high * phaseY;
          mShadowBuffers[3] = open * phaseY;
          mShadowBuffers[5] = low * phaseY;
          mShadowBuffers[7] = close * phaseY;
        } else if (open < close) {
          mShadowBuffers[1] = high * phaseY;
          mShadowBuffers[3] = close * phaseY;
          mShadowBuffers[5] = low * phaseY;
          mShadowBuffers[7] = open * phaseY;
        } else {
          mShadowBuffers[1] = high * phaseY;
          mShadowBuffers[3] = open * phaseY;
          mShadowBuffers[5] = low * phaseY;
          mShadowBuffers[7] = mShadowBuffers[3];
        }

        trans.pointValuesToPixel(mShadowBuffers);

        // draw the shadows

        if (dataSet.getShadowColorSameAsCandle()) {

          if (open > close)
            mRenderPaint.setColor(
                dataSet.getDecreasingColor() == ColorTemplate.COLOR_NONE ?
                    dataSet.getColor(j) :
                    dataSet.getDecreasingColor()
            );

          else if (open < close)
            mRenderPaint.setColor(
                dataSet.getIncreasingColor() == ColorTemplate.COLOR_NONE ?
                    dataSet.getColor(j) :
                    dataSet.getIncreasingColor()
            );

          else
            mRenderPaint.setColor(
                dataSet.getNeutralColor() == ColorTemplate.COLOR_NONE ?
                    dataSet.getColor(j) :
                    dataSet.getNeutralColor()
            );

        } else {
          mRenderPaint.setColor(
              dataSet.getShadowColor() == ColorTemplate.COLOR_NONE ?
                  dataSet.getColor(j) :
                  dataSet.getShadowColor()
          );
        }

        mRenderPaint.setStyle(Paint.Style.STROKE);

        c.drawLines(mShadowBuffers, mRenderPaint);

        // calculate the body

        mBodyBuffers[0] = xIndex - 0.5f + barSpace;
        mBodyBuffers[1] = close * phaseY;
        mBodyBuffers[2] = (xIndex + 0.5f - barSpace);
        mBodyBuffers[3] = open * phaseY;

        trans.pointValuesToPixel(mBodyBuffers);

        // draw body differently for increasing and decreasing entry
        if (open > close) { // decreasing

          if (dataSet.getDecreasingColor() == ColorTemplate.COLOR_NONE) {
            mRenderPaint.setColor(dataSet.getColor(j));
          } else {
            mRenderPaint.setColor(dataSet.getDecreasingColor());
          }

          mRenderPaint.setStyle(dataSet.getDecreasingPaintStyle());

          c.drawRect(
              mBodyBuffers[0], mBodyBuffers[3],
              mBodyBuffers[2], mBodyBuffers[1],
              mRenderPaint);

        } else if (open < close) {

          if (dataSet.getIncreasingColor() == ColorTemplate.COLOR_NONE) {
            mRenderPaint.setColor(dataSet.getColor(j));
          } else {
            mRenderPaint.setColor(dataSet.getIncreasingColor());
          }

          mRenderPaint.setStyle(dataSet.getIncreasingPaintStyle());

          c.drawRect(
              mBodyBuffers[0], mBodyBuffers[1],
              mBodyBuffers[2], mBodyBuffers[3],
              mRenderPaint);
        } else { // equal values

          if (dataSet.getNeutralColor() == ColorTemplate.COLOR_NONE) {
            mRenderPaint.setColor(dataSet.getColor(j));
          } else {
            mRenderPaint.setColor(dataSet.getNeutralColor());
          }

          c.drawLine(
              mBodyBuffers[0], mBodyBuffers[1],
              mBodyBuffers[2], mBodyBuffers[3],
              mRenderPaint);
        }
      } else {

        mRangeBuffers[0] = xIndex;
        mRangeBuffers[1] = high * phaseY;
        mRangeBuffers[2] = xIndex;
        mRangeBuffers[3] = low * phaseY;

        mOpenBuffers[0] = xIndex - 0.5f + barSpace;
        mOpenBuffers[1] = open * phaseY;
        mOpenBuffers[2] = xIndex;
        mOpenBuffers[3] = open * phaseY;

        mCloseBuffers[0] = xIndex + 0.5f - barSpace;
        mCloseBuffers[1] = close * phaseY;
        mCloseBuffers[2] = xIndex;
        mCloseBuffers[3] = close * phaseY;

        trans.pointValuesToPixel(mRangeBuffers);
        trans.pointValuesToPixel(mOpenBuffers);
        trans.pointValuesToPixel(mCloseBuffers);

        // draw the ranges
        int barColor;

        if (open > close)
          barColor = dataSet.getDecreasingColor() == ColorTemplate.COLOR_NONE
              ? dataSet.getColor(j)
              : dataSet.getDecreasingColor();
        else if (open < close)
          barColor = dataSet.getIncreasingColor() == ColorTemplate.COLOR_NONE
              ? dataSet.getColor(j)
              : dataSet.getIncreasingColor();
        else
          barColor = dataSet.getNeutralColor() == ColorTemplate.COLOR_NONE
              ? dataSet.getColor(j)
              : dataSet.getNeutralColor();

        mRenderPaint.setColor(barColor);
        c.drawLine(
            mRangeBuffers[0], mRangeBuffers[1],
            mRangeBuffers[2], mRangeBuffers[3],
            mRenderPaint);
        c.drawLine(
            mOpenBuffers[0], mOpenBuffers[1],
            mOpenBuffers[2], mOpenBuffers[3],
            mRenderPaint);
        c.drawLine(
            mCloseBuffers[0], mCloseBuffers[1],
            mCloseBuffers[2], mCloseBuffers[3],
            mRenderPaint);

      }
    }
  }

  @Override public void initBuffers() {

  }

  @Override public void drawValues(Canvas c) {
    // if values are drawn
    if (mChart.getStickData().getYValCount() < mChart.getMaxVisibleCount()
        * mViewPortHandler.getScaleX()) {

      List<ICandleDataSet> dataSets = mChart.getStickData().getDataSets();

      for (int i = 0; i < dataSets.size(); i++) {

        ICandleDataSet dataSet = dataSets.get(i);

        if (!dataSet.isDrawValuesEnabled() || dataSet.getEntryCount() == 0)
          continue;

        // apply the text-styling defined by the DataSet
        applyValueTextStyle(dataSet);

        Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());

        int minx = Math.max(mMinX, 0);
        int maxx = Math.min(mMaxX + 1, dataSet.getEntryCount());

        float[] positions = trans.generateTransformedValuesCandle(
            dataSet, mAnimator.getPhaseX(), mAnimator.getPhaseY(), minx, maxx);

        float yOffset = Utils.convertDpToPixel(5f);

        for (int j = 0; j < positions.length; j += 2) {

          float x = positions[j];
          float y = positions[j + 1];

          if (!mViewPortHandler.isInBoundsRight(x))
            break;

          if (!mViewPortHandler.isInBoundsLeft(x) || !mViewPortHandler.isInBoundsY(y))
            continue;

          CandleEntry entry = dataSet.getEntryForIndex(j / 2 + minx);

          drawValue(c, dataSet.getValueFormatter(), entry.getHigh(), entry, i, x, y - yOffset, dataSet.getValueTextColor(j / 2));
        }
      }
    }
  }

  @Override public void drawExtras(Canvas c) {

  }

  @Override public void drawHighlighted(Canvas c, Highlight[] indices) {
    StickData stickData = mChart.getStickData();

    for (Highlight high : indices) {

      final int minDataSetIndex = high.getDataSetIndex() == -1
          ? 0
          : high.getDataSetIndex();
      final int maxDataSetIndex = high.getDataSetIndex() == -1
          ? stickData.getDataSetCount()
          : (high.getDataSetIndex() + 1);
      if (maxDataSetIndex - minDataSetIndex < 1)
        continue;

      for (int dataSetIndex = minDataSetIndex;
          dataSetIndex < maxDataSetIndex;
          dataSetIndex++) {

        int xIndex = high.getXIndex(); // get the
        // x-position

        ICandleDataSet set = mChart.getStickData().getDataSetByIndex(dataSetIndex);

        if (set == null || !set.isHighlightEnabled())
          continue;

        CandleEntry e = set.getEntryForXIndex(xIndex);

        if (e == null || e.getXIndex() != xIndex)
          continue;

        float lowValue = e.getLow() * mAnimator.getPhaseY();
        float highValue = e.getHigh() * mAnimator.getPhaseY();
                /*float y = (lowValue + highValue) / 2f;*/
        /**
         * spence customer
         */
        float y = high.getValue();
        float[] pts = new float[]{
            xIndex, y
        };

        mChart.getTransformer(set.getAxisDependency()).pointValuesToPixel(pts);

        // draw the lines
        drawHighlightLines(c, pts, set);
      }
    }
  }
}
